<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CMS首页</title>
    <link href="/style/bootstrap.min.css" rel="stylesheet" />
    <link href="/style/bootstrap-icons.min.css" rel="stylesheet">
    <script src="/js/jquery.min.js"></script>
    <script src="/js/bootstrap.bundle.min.js"></script>
    <script src="/js/htmx.min.js"></script>
    <script src="/js/handlebars.min.js"></script>
    <script src="/js/client-side-templates.js"></script>
    <style>
        .nav-link.active{
            background-color: green;
            color:red;
        }
    </style>
</head>

<body>
    <header class="navbar navbar-expand-lg navbar-light bg-light">
        <div class="container-fluid">
            <a class="navbar-brand" href="#">首页</a>
            <div id="profile-container" class="d-flex" hx-get="/api/auth/profile" hx-trigger="load"
                hx-ext="client-side-templates" handlebars-template="profile-template" hx-swap="innerHTML"></div>
        </div>
    </header>
    <div id="categories-container" class="container mb-3" hx-get="/api/categories" hx-trigger="load"
    hx-ext="client-side-templates" handlebars-template="categories-template" hx-swap="innerHTML"
    hx-vals="javascript:{selectedCategoryId:localStorage.getItem('selectedCategoryId')??''}"
    ></div>
    <div id="tags-container" class="container mb-3" hx-get="/api/tags" hx-trigger="load"
    hx-ext="client-side-templates" handlebars-template="tags-template" hx-swap="innerHTML"
    hx-vals="javascript:{selectedTagId:localStorage.getItem('selectedTagId')??''}"
    ></div>
    <div class="container mb-3">
        <input id="search-keyword" class="form-control" placeholder="请输入关键字"
        hx-get="/api/articles" hx-target="#article-list" hx-trigger="keyup"
        hx-vals="javascript:{keyword:document.getElementById('search-keyword').value,selectedCategoryId:localStorage.getItem('selectedCategoryId')??'',selectedTagId:localStorage.getItem('selectedTagId')??''}"
        hx-ext="client-side-templates" 
        handlebars-template="article-list-template" 
        hx-swap="innerHTML"
        />

    </div>
    <div class="container" id="article-list" hx-trigger="load"
                hx-get="/api/articles"
                hx-ext="client-side-templates" 
                handlebars-template="article-list-template" 
                hx-swap="innerHTML"
    ></div>
    <script id="profile-template" type="text/x-handlebars-template">
        <span hx-xx>欢迎 {{user.username}}</span>
    </script>
    <script id="categories-template" type="text/x-handlebars-template">
        <ul class="nav nav-pill">
            <li class="nav-item">
                <a 
                onclick="setSelectedCategoryId('')"
                class="nav-link {{#if (eq selectedCategoryId '')}}active{{/if}}" 
                href="#"
                hx-get="/api/article"
                hx-target="#article-list"
                hx-ext="client-side-templates" 
                hx-vals="javascript:{keyword:document.getElementById('search-keyword').value,selectedTagId:localStorage.getItem('selectedTagId')??''}"
                handlebars-template="article-list-template" 
                hx-swap="innerHTML"
                >全部</a>
              </li>
            {{#each categories}}
              <li class="nav-item">
                <a 
                onclick="setSelectedCategoryId('{{id}}')"
                class="nav-link {{#if (eq ../selectedCategoryId this.id)}}active{{/if}}" 
                href="#"
                hx-get="/api/articles?categoryId={{id}}"
                hx-vals="javascript:{keyword:document.getElementById('search-keyword').value,selectedTagId:localStorage.getItem('selectedTagId')??''}"
                hx-target="#article-list"
                hx-ext="client-side-templates" 
                handlebars-template="article-list-template" 
                hx-swap="innerHTML"
                >{{name}}</a>
              </li>
            {{/each}}

        </ul>
    </script>
    <script id="tags-template" type="text/x-handlebars-template">
        <ul class="nav nav-pill">
            <li class="nav-item">
                <a 
                onclick="setSelectedTagId('')"
                class="nav-link {{#if (eq selectedTagId '')}}active{{/if}}" 
                href="#"
                hx-get="/api/articles"
                hx-target="#article-list"
                hx-ext="client-side-templates" 
                handlebars-template="article-list-template" 
                hx-vals="javascript:{keyword:document.getElementById('search-keyword').value,selectedCategoryId:localStorage.getItem('selectedCategoryId')??''}"
                hx-swap="innerHTML"
                >全部</a>
              </li>
            {{#each tags}}
              <li class="nav-item">
                <a 
                onclick="setSelectedTagId('{{id}}')"
                class="nav-link {{#if (eq ../selectedTagId this.id)}}active{{/if}}" 
                href="#"
                hx-get="/api/articles?tagId={{id}}"
                hx-target="#article-list"
                hx-ext="client-side-templates" 
                hx-vals="javascript:{keyword:document.getElementById('search-keyword').value,selectedCategoryId:localStorage.getItem('selectedCategoryId')??''}"
                handlebars-template="article-list-template" 
                hx-swap="innerHTML"
                >{{name}}</a>
              </li>
            {{/each}}
        </ul>
    </script>
    <script id="article-list-template" type="text/x-handlebars-template">
        <ul class="list-group">
            {{#each articles}}
              <li class="list-group-item">
                <h5><a href="/article.html?id={{id}}">{{title}}</a></h5>
                <p>分类
                    {{#each categories}}
                      <a
                       onclick="setSelectedCategoryId('{{id}}')"
                       href="#"
                       hx-get="/api/articles?categoryId={{id}}"
                       hx-target="#article-list"
                      >{{name}}</a>
                    {{/each}}
                </p>
                <p>标签
                    {{#each tags}}
                      <a
                       onclick="setSelectedTag('{{id}}')"
                       href="#"
                       hx-get="/api/articles?tagId={{id}}"
                       hx-target="#article-list"
                      >{{name}}</a>
                    {{/each}}
                </p>
              </li>
            {{/each}}
        </ul>
    </script>
    <script>
        Handlebars.registerHelper('eq',function(a,b){
        console.log('a=',a,'b=',b);
          return a == b;
        });
        function setSelectedCategoryId(categoryId){
            localStorage.setItem('selectedCategoryId',categoryId);
            fetch(`/api/categories?selectedCategoryId=${categoryId}`)
            .then(res=>res.json())
            .then(data=>{
                const templateSource = document.getElementById('categories-template').innerHTML;
                const render = Handlebars.compile(templateSource);
                const html = render(data);
                const categoriesContainer= document.getElementById('categories-container');
                categoriesContainer.innerHTML = html;
                htmx.process(categoriesContainer);
            })
        }
        function setSelectedTagId(tagId){
            localStorage.setItem('selectedTagId',tagId);
            fetch(`/api/tags?selectedTagId=${tagId}`)
            .then(res=>res.json())
            .then(data=>{
                const templateSource = document.getElementById('tags-template').innerHTML;
                const render = Handlebars.compile(templateSource);
                const html = render(data);
                const tagsContainer= document.getElementById('tags-container');
                tagsContainer.innerHTML = html;
                htmx.process(tagsContainer);
            })

        }
        $('body').on('htmx:configRequest', function (event) {
            //每次发请求之前先把本地保存的token附加到请求里面
            const accessToken = localStorage.getItem('access_token');
            if (accessToken) {
                event.detail.headers['Authorization'] = `Bearer ${accessToken}`;
            }
        });
    </script>
    <script>
        //当前是否正在刷新Token
        let isRefreshingAccessToken = false;
        //刷新Token的订阅者
        const refreshSubscribers = [];
        function subscribeTokenRefresh(callback) {
            refreshSubscribers.push(callback);
        }
        function onRefreshed(newAccessToken) {
            refreshSubscribers.forEach(callback => callback(newAccessToken));
            refreshSubscribers.length = 0;
        }


        async function refreshAccessToken() {
            if (!isRefreshingAccessToken) {
                isRefreshingAccessToken = true;//设置为正在刷新Token
                try {
                    const response = await fetch('/api/auth/refresh-token', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ refreshToken: localStorage.getItem('refresh_token') })
                    })
                    const data = await response.json();
                    if (data.success) {
                        localStorage.setItem('access_token', data.access_token);
                        localStorage.setItem('refresh_token', data.refresh_token);
                        onRefreshed(data.access_token);
                        return true;
                    } else {
                        window.location.href = '/login.html';
                        return false;
                    }
                } catch (error) {
                    window.location.href = '/login.html';
                    return false;
                }finally{
                    isRefreshingAccessToken=false;
                }
            }

        }
        function reloadProfileContainer(accessToken,event) {
            fetch(event.detail.pathInfo.path, {
                headers: { Authorization: `Bearer ${accessToken}` }
            }).then(res => res.json())
                .then(data => {
                    const templateSource = document.getElementById('profile-template').innerHTML;
                    const template = Handlebars.compile(templateSource);
                    const html = template(data);
                    event.target.innerHTML=html;
                    //处理指定DOM元素素上的htmx指令,让HTMX识别这些指令 进行后续处理
                    htmx.process(event.target);
                }).catch(error => console.error('Error fetching profile:', error))
        }
        $('body').on('htmx:afterOnLoad', async function (event) {
            //如果说响应的状态码是401，说明访问失败了
            if (event.detail.xhr.status === 401) {//可能是因为access_token过期了,可以尝试自动用
                //如果当前没有正在刷新Token
                if (!isRefreshingAccessToken) {
                    const success = await refreshAccessToken();
                    if (success) {//说明刷新Token成功了
                        const accessToken = localStorage.getItem('access_token');
                        reloadProfileContainer(accessToken,event)
                    }
                } else {
                    subscribeTokenRefresh((newAccessToken) => {
                        reloadProfileContainer(newAccessToken,event)
                    });
                }
            }
        })
    </script>
</body>

</html>